package com.atguigu.myssm.myspringmvc;

import com.atguigu.myssm.io.BeanFactory;
import com.atguigu.myssm.io.ClassPathXmlApplicationContext;
import com.atguigu.myssm.util.StringUtil;

import javax.servlet.ServletException;
import javax.servlet.annotation.WebServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;

@WebServlet("*.do")
public class DispatcherServlet extends ViewBaseServlet {

    BeanFactory beanFactory = null;

    public void init() throws ServletException {
        super.init();
        beanFactory = new ClassPathXmlApplicationContext();
    }

    @Override
    protected void service(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
        req.setCharacterEncoding("UTF-8");
        String servletPath = req.getServletPath();
        servletPath = servletPath.substring(1);
        int indexOf = servletPath.lastIndexOf(".do");
        servletPath = servletPath.substring(0,indexOf);
        Object controllerObj = beanFactory.getBean(servletPath);
        String operate = req.getParameter("operate");
        if(StringUtil.isEmpty(operate)) {
            operate = "index";
        }
        try {
            Method[] declaredMethods = controllerObj.getClass().getDeclaredMethods();
            for(Method method : declaredMethods) {
                if(operate.equals(method.getName())) {
                    Parameter[] parameters = method.getParameters();
                    Object[] objects = new Object[parameters.length];
                    for (int i = 0; i < parameters.length; i++) {
                        Parameter parameter = parameters[i];
                        String name = parameter.getName();
                        if ("req".equals(name)){
                            objects[i] = req;
                        } else if ("response".equals(name)) {
                            objects[i] = resp;
                        } else if ("session".equals(name)) {
                            objects[i] = req.getSession();
                        } else {
                            String parameterTemp = req.getParameter(name);
                            String typeName = parameter.getType().getName();
                            Object paraObj = parameterTemp;
                            if(paraObj != null) {
                                if("java.lang.Integer".equals(typeName) ) {
                                    paraObj = Integer.parseInt(parameterTemp);
                                }
                            }
                            objects[i] = paraObj;
                        }
                    }
                    method.setAccessible(true);
                    Object returnObj = method.invoke(controllerObj, objects);
                    String methodReturn = (String) returnObj;
                    if (methodReturn.startsWith("redirect:")) {
                        String redirect = methodReturn.substring("redirect:".length());
                        resp.sendRedirect(redirect);
                    } else {
                        super.processTemplate(methodReturn,req,resp);
                    }
                }
            }
        } catch (InvocationTargetException e) {
            throw new RuntimeException(e);
        } catch (IllegalAccessException e) {
            throw new RuntimeException(e);
        }
    }
}
